<?php

namespace app\admin\controller\goods;

use app\admin\model\GoodsType;
use app\admin\model\Products;
use app\common\controller\Backend;
use app\admin\validate\Goods as GoodsValidate;
use fast\Tree;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
use app\admin\validate\Products as ProductsValidate;

/**
 * 
 *
 * @icon fa fa-circle-o
 */
class Goods extends Backend
{
    private $spec = [];//规格数组
    static $sku_item;//规格
    static $deep_key;//规格深度
    static $total_item;//总规格

    /**
     * Multi方法可批量修改的字段
     */
    protected $multiFields = 'status,market_switch,top_switch';

    /**
     * 快速搜索时执行查找的字段
     */
    protected $searchFields = 'id,bn,name';

    /**
     * Goods模型对象
     * @var \app\admin\model\Goods
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Goods;

        $isNormalVirtual = [
            1 => __('Normal'),
            2 => __('Virtual'),
        ];
        $this->assign('isNormalVirtual',$isNormalVirtual);
        $this->assignconfig('isNormalVirtual',$isNormalVirtual);
    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
    

    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询 给传递过来的参数增加表名，防止字段不明确
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax())
        {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField'))
            {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                    ->with(['category','goodstype','brand'])
                    ->where($where)
                    ->order($sort, $order)
                    ->count();

            $list = $this->model
                    ->with(['category','goodstype','brand'])
                    ->where($where)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();

            foreach ($list as $row) {
                //$row['is_nomal_virtual'] = ($row['is_nomal_virtual'] == 1) ? '正常' : '虚拟';
                
            }
            $list = collection($list)->toArray();
            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 添加goods
     */
    public function add()
    {
        //分类树形结构 渲染 begin
        $tree = Tree::instance();
        $tree->init(collection(model('app\common\model\Category')->where('type','=','goods')->order('weigh desc,id desc')->select())->toArray(), 'pid');
        $categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
        $categorydata = [];
        foreach ($categorylist as $k => $v) {
            $categorydata[$v['id']] = $v;
        }

        $this->view->assign("parentList", $categorydata);
        //分类树形结构 渲染 end


        if ($this->request->isPost()) {

            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                $result = false;
                Db::startTrans();
                try {
                    //整理获取商品数据
                    $data = $this->checkGoodsInfo();
                    $result = $this->model->allowField(true)->save($data['goods']);

                    //添加products 获取货品数据
                    if ($result){
                        $productId = $this->addProductInfo($data,$this->model->id);
                    }

                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->with('products')->find($ids);

        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }

        //分类树形结构 渲染 begin
        $tree = Tree::instance();
        $tree->init(collection(model('app\common\model\Category')->where('type','=','goods')->order('weigh desc,id desc')->select())->toArray(), 'pid');
        $categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
        $categorydata = [];
        foreach ($categorylist as $k => $v) {
            $categorydata[$v['id']] = $v;
        }

        $this->view->assign("parentList", $categorydata);
        //分类树形结构 渲染 end

        $this->assign('data', $row);
        $this->assign('products', $row['products']);

        //规格开启 or 关闭
        if ($row['spes_desc'] || $row['new_spec']) {
            $this->assign('open_spec', '1');
        } else {
            $this->assign('open_spec', '0');
        }

        //获取 商品类型规格 数据
        $res            = $this->getEditSpec($row['goods_type_id'], $row);
        $this->assign('spec_html', $res['data']);


        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                //$params = $this->preExcludeFields($params);
                $result = false;
                Db::startTrans();
                try {

                    //$result = $row->allowField(true)->save($params);

                    //整理获取商品数据
                    $data = $this->checkGoodsInfo(true);
                    //更新商品数据
                    $result = $this->model->updateGoods($data['goods']['id'], $data['goods']);

                    //更新products 获取货品数据
                    if ($result){
                        $productId = $this->updateProductInfo($data,$data['goods']['id']);
                    }


                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * add货品数据
     * @return mixed
     */
    public function addProductInfo($data,$goods_id = 0){
        $productsModel = new Products();
        $open_spec = input('post.open_spec', 0);
        if ($open_spec) {
            //多规格 货品数据
            $product       = input('post.product/a', []);

            $total_stock   = $price = $costprice = $mktprice = 0;
            $isExitDefalut = false;
            foreach ($product as $key => $val) {
                $tmp_product['goods']['price']        = isset($val['price']) ? $val['price'] : 0;
                $tmp_product['goods']['costprice']    = isset($val['costprice']) ? $val['costprice'] : 0;
                $tmp_product['goods']['mktprice']     = isset($val['mktprice']) ? $val['mktprice'] : 0;
                $tmp_product['goods']['market_switch']   = isset($val['market_switch']) ? $val['market_switch'] : $productsModel::MARKETABLE_DOWN;
                $tmp_product['goods']['stock']        = isset($val['stock']) ? $val['stock'] : 0;
                $sn                                   = get_sn(4);
                $tmp_product['goods']['sn']           = isset($val['sn']) ? $val['sn'] : $sn;
                $tmp_product['goods']['product_spes'] = $key;
                $tmp_product['goods']['image']        = ($val['image']) ? $val['image'] : $data['goods']['image'];
                $tmp_product['goods']['is_defalut']   = isset($val['is_defalut']) ? $productsModel::DEFALUT_YES : $productsModel::DEFALUT_NO;

                if ($tmp_product['goods']['is_defalut'] == $productsModel::DEFALUT_YES) {
                    $isExitDefalut = true;
                }
                $checkData = $this->checkProductInfo($tmp_product, $goods_id);

                if (!$checkData['status']) {
                    $result['msg'] = $checkData['msg'];
                    Db::rollback();
                    $this->error($checkData['msg']);
                }
                $data['product'] = $checkData['data']['product'];

                $product_id      = $productsModel->doAdd($data['product']);
                if (!$product_id) {
                    Db::rollback();
                    $this->error('products添加失败!');
                }
                if ($tmp_product['goods']['is_defalut'] == $productsModel::DEFALUT_YES) {//todo 取商品默认价格
                    $price     = $tmp_product['goods']['price'];
                    $costprice = $tmp_product['goods']['costprice'];
                    $mktprice  = $tmp_product['goods']['mktprice'];
                }
            }
            if (!$isExitDefalut) {
                Db::rollback();
                $this->error('请选择默认货品');
            }

            //更新总库存
            //$upData['stock']     = $total_stock;
            $upData['price']     = $price;
            $upData['costprice'] = $costprice;
            $upData['mktprice']  = $mktprice;
            $this->model->updateGoods($goods_id, $upData);
        } else {
            $sn                          = get_sn(4);
            $data['goods']['sn']         = input('post.row.sn', $sn);//货品编码
            $data['goods']['is_defalut'] = $productsModel::DEFALUT_YES;
            //$data['product'] = $checkData['data']['product'];
            $checkData = $this->checkProductInfo($data, $goods_id);

            if (!$checkData['status']) {
                Db::rollback();
                $this->error($checkData['msg']);
            }
            $data       = $checkData['data'];
            $product_id = $productsModel->doAdd($data['product']);
            if (!$product_id) {
                Db::rollback();
                $this->error('products添加失败!');
            }
        }

        //更新商品总库存
        $total_stock          = $productsModel->where('goods_id', '=', $goods_id)->sum('stock');
        $upDataGoods['stock'] = $total_stock;
        $res                  = $this->model->updateGoods($goods_id, $upDataGoods);
        if ($res === false) {
            Db::rollback();
            $this->error('更新商品总库存失败!');
        }

        //array_push($data, ['goods_id' => $goods_id]);
        //hook('addgoodsafter', $data);//添加商品后增加钩子

        $result['msg']    = '保存成功';
        $result['status'] = true;
        return $result;
    }

    /**
     * update货品数据
     * @param $data
     * @param int $goods_id
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function updateProductInfo($data,$goods_id = 0){
        //获取原货品数据
        $productsModel = new Products();
        $products   = $productsModel->field('id')->where(['goods_id' => $goods_id])->select();
        $productIds = array_column($products, 'id');

        //多规格 是否开启
        $open_spec = input('post.open_spec', 0);

        if ($open_spec) {
            //多规格
            $product       = input('post.product/a', []);
            $total_stock   = $price = $costprice = $mktprice = 0;
            $isExitDefalut = false;
            $exit_product  = [];
            if (isset($product['id'])) unset($product['id']);

            foreach ($product as $key => $val) {
                $tmp_product['goods']['price']        = !empty($val['price']) ? $val['price'] : 0;
                $tmp_product['goods']['costprice']    = !empty($val['costprice']) ? $val['costprice'] : 0;
                $tmp_product['goods']['mktprice']     = !empty($val['mktprice']) ? $val['mktprice'] : 0;
                $tmp_product['goods']['market_switch']   = !empty($val['market_switch']) ? $val['market_switch'] : $productsModel::MARKETABLE_DOWN;
                $tmp_product['goods']['stock']        = !empty($val['stock']) ? $val['stock'] : 0;
                $sn                                   = get_sn(4);
                $tmp_product['goods']['sn']           = !empty($val['sn']) ? $val['sn'] : $sn;
                $tmp_product['goods']['product_spes'] = $key;
                $tmp_product['goods']['image']        = ($val['image']) ? $val['image'] : $data['goods']['image'];
                $tmp_product['goods']['is_defalut']   = !empty($val['is_defalut']) ? $productsModel::DEFALUT_YES : $productsModel::DEFALUT_NO;
                if ($tmp_product['goods']['is_defalut'] == $productsModel::DEFALUT_YES) {
                    $isExitDefalut = true;
                }

                //检查获取货品数据 begin 原有和新增
                if (isset($val['id']) && $val['id']) {
                    $tmp_product['product']['id'] = $val['id'];
                    $checkData                    = $this->checkProductInfo($tmp_product, $goods_id, true);

                } else {
                    unset($tmp_product['product']['id']);
                    $checkData = $this->checkProductInfo($tmp_product, $goods_id);
                }
                //检查获取货品数据 end

                if (!$checkData['status']) {
                    Db::rollback();
                    $this->error($checkData['msg']);
                }
                $data['product'] = $checkData['data']['product'];

                //更新或新增货品数据 begin
                if (isset($val['id']) && $val['id']) {
                    $productRes = $productsModel->updateProduct($val['id'], $data['product']);
                    if (in_array($val['id'], $productIds)) {
                        $productIds = unsetByValue($productIds, $val['id']);
                    }
                    if ($val['id']) {
                        $exit_product[] = $val['id'];
                    }
                } else {
                    unset($data['product']['id']);
                    $productRes = $productsModel->doAdd($data['product']);
                    if (is_numeric($productRes)) {
                        $exit_product[] = $productRes;
                    }
                }
                //更新或新增货品数据 end

                if ($productRes === false) {
                    Db::rollback();
                    $this->error('货品数据保存失败');
                }

                //$total_stock = $total_stock + $tmp_product['goods']['stock'];
                if ($tmp_product['goods']['is_defalut'] == $productsModel::DEFALUT_YES) {//todo 取商品默认价格
                    $price     = $tmp_product['goods']['price'];
                    $costprice = $tmp_product['goods']['costprice'];
                    $mktprice  = $tmp_product['goods']['mktprice'];
                }
            }
            if (!$isExitDefalut) {
                // $result['msg'] = '请选择默认货品';
                Db::rollback();
                $this->error('请选择默认货品');
            }
            //更新商品信息
            //$upData['stock']     = $total_stock;
            $upData['price']     = $price;
            $upData['costprice'] = $costprice;
            $upData['mktprice']  = $mktprice;
            $this->model->updateGoods($goods_id, $upData);

            //删除多余规格
            $where = [
                'id' => ['not in', $exit_product],
                'goods_id' => $goods_id,
            ];
            $productsModel->where($where)->delete();
        } else {
            $sn                          = get_sn(4);
            $data['goods']['sn']         = input('post.row.sn', $sn);//货品编码
            $data['goods']['is_defalut'] = $productsModel::DEFALUT_YES;
            //$data['product'] = $checkData['data']['product'];
            $data['product']['id'] = input('post.product.id/d', 0);

            //检查获取货品数据 begin 原有和新增
            if ($data['product']['id']) {
                $checkData = $this->checkProductInfo($data, $goods_id, true);
            } else {
                $checkData = $this->checkProductInfo($data, $goods_id);
            }
            //检查获取货品数据 end

            if (!$checkData['status']) {
                Db::rollback();
                $this->error($checkData['msg']);
            }
            $data = $checkData['data'];

            //更新或新增货品数据 begin
            if ($data['product']['id']) {
                if (in_array($data['product']['id'], $productIds)) {
                    $productIds = unsetByValue($productIds, $data['product']['id']);
                }
                $updateRes = $productsModel->updateProduct($data['product']['id'], $data['product']);
            } else {
                $updateRes = $productsModel->doAdd($data['product']);
            }
            //更新或新增货品数据 end

            if ($updateRes === false) {
                // $result['msg'] = '货品数据保存失败';
                Db::rollback();
                $this->error('货品数据保存失败');
            }
        }
        //删除多余货品数据
        if ($productIds) {
            $productsModel->deleteProduct($productIds);
        }

        //更新商品总库存
        $total_stock          = $productsModel->where('goods_id', '=', $goods_id)->sum('stock');
        $upDataGoods['stock'] = $total_stock;

        $res = $this->model->updateGoods($goods_id, $upDataGoods);
        if ($res === false) {
            // $result['msg'] = '总库存更新失败';
            Db::rollback();
            $this->error('总库存更新失败');
        }

        //hook('editgoodsafter', $data);//编辑商品后增加钩子

        $result['msg']    = '保存成功';
        $result['status'] = true;
        return $result;
    }

    /**
     * 检查并组装货品数据
     *
     * @return bool
     */
    private function checkProductInfo($data, $goods_id = 0, $isEdit = false)
    {
        $result = [
            'status' => false,
            'msg'    => '',
            'data'   => '',
        ];

        if (!$goods_id) {
            $this->error('error');
        }
        $productsModel = new Products();
        //单规格
        $data['product']['goods_id']   = $goods_id;
        $data['product']['sn']         = $data['goods']['sn'];//货品编码
        $data['product']['price']      = $data['goods']['price'];//货品价格
        $data['product']['costprice']  = $data['goods']['costprice'];//货品成本价
        $data['product']['mktprice']   = $data['goods']['mktprice'];//货品市场价
        $data['product']['market_switch'] = $data['goods']['market_switch'];//是否上架
        $data['product']['stock']      = $data['goods']['stock'];//货品库存
        $data['product']['image']   = $data['goods']['image'];//货品图片
        $data['product']['is_defalut'] = isset($data['goods']['is_defalut']) ? $data['goods']['is_defalut'] : $productsModel::DEFALUT_YES;//是否默认货品
        $open_spec                     = input('post.open_spec', 0);
        if ($open_spec && $data['goods']['product_spes']) {
            $data['product']['spes_desc'] = $data['goods']['product_spes'];
        }
        if (!$data['product']['sn']) {
            $data['product']['sn'] = get_sn(4);
        }
        if ($isEdit) {
            $validate = new ProductsValidate();
            if (!$validate->scene('edit')->check($data['product'])) {
                $result['msg'] = $validate->getError();
                return $result;
            }
        } else {
            $validate = new ProductsValidate();
            if (!$validate->check($data['product'])) {
                $result['msg'] = $validate->getError();
                return $result;
            }
        }

        $result['data']   = $data;
        $result['status'] = true;
        return $result;
    }

    /**
     * 获取 商品类型 的 属性 参数
     * @throws \think\Exception
     */
    public function getSpec()
    {
        $this->view->engine->layout(false);

        $type_id = $this->request->request('type_id');

        if ($type_id) {
            $goodsTypeModel = new GoodsType();
            $res            = $goodsTypeModel->getTypeValue($type_id);
            //$this->success('获取成功',null,$res);
            $html       = '';
            $customSpec = false;//是否可以使用自定义规格
            if ($res['status'] == true) {
                $this->assign('typeInfo', $res['data']);
                if ($res['data']['spec']) {
                    $spec = [];
                    foreach ($res['data']['spec'] as $key => $val) {
                        $spec[$key]['name']      = $val['spec']['name'];
                        $spec[$key]['specValue'] = $val['spec']['spec_value'];
                    }
                    $this->assign('spec', $spec);
                    if (count($spec) <= 2) {//规格超过2种的，不允许自定义
                        $customSpec = true;
                    }
                }
                $this->assign('customSpec', $customSpec);

                if (!$res['data']['spec']) {
                    $this->assign('canOpenSpec', 'false');
                } else {
                    $this->assign('canOpenSpec', 'true');
                }

                //获取参数信息
                $this->assign('typeParams', $res['data']['params']);

                $html = $this->view->fetch('getSpec');
                $this->success('获取成功',null,$html);
            }
        }
        $this->error('获取失败');
    }

    /**
     * 获取 属性 组合 html
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getSpecHtml()
    {

        $this->view->engine->layout(false);

        $spec         = $this->request->request('spec/a');
        $goods_id     = $this->request->request('goods_id');
        $goodsDefault = $this->request->request('row/a');
        $products     = [];

        if ($goods_id) {
            $goods      = $this->model->with('products')->field('id,image')->find($goods_id);
            if (!$goods) {
                $this->error('获取失败');
            }
            $products = $goods['data']->products;
        }

        $html = '';
        if ($spec) {
            $specValue = [];
            $total     = count($spec);
            foreach ($spec as $key => $val) {
                $this->spec[] = $key;
            }
            $items = $this->getSkuItem($spec, -1);

            foreach ((array)$items as $key => $val) {
                $items[$key]['price']     = $goodsDefault['price'];
                $items[$key]['costprice'] = $goodsDefault['costprice'];
                $items[$key]['mktprice']  = $goodsDefault['mktprice'];
                if (isset($goodsDefault['sn']) && $goodsDefault['sn']) {
                    $items[$key]['sn'] = $goodsDefault['sn'] . '-' . ($key + 1);
                }else{
                    $items[$key]['sn'] = '';
                }
                $items[$key]['stock'] = $goodsDefault['stock'];
            }
            if ($products) {
                foreach ($items as $key => $val) {
                    foreach ($products as $product) {
                        if ($val['spec_name'] == $product['spes_desc']) {
                            $items[$key]               = array_merge((array)$val, (array)$product);
                            $items[$key]['product_id'] = $product['id'];
                        }
                    }
                }
            }
            $this->assign('items', $items);
            $html             = $this->view->fetch('getSpecHtml');
        }
        

        $this->success('组合成功',null,$html);
    }

    /**
     * 商品属性组合
     * @param $data
     * @param int $index
     * @param array $sku_item
     * @return array
     */
    private function getSkuItem($data, $index = -1, $sku_item = [])
    {
        self::$total_item = array();
        if ($index < 0) {
            self::$deep_key = count($data) - 1;
            $this->getSkuItem($data, 0, $sku_item);
        } else {
            if ($index == 0) {
                $first = $data[$this->spec[$index]];

                foreach ($first as $key => $value) {
                    self::$total_item[$key] = array(
                        'spec_name' => $this->spec[$index] . ':' . $value,
                        'spec_key'  => $this->spec[$index],
                    );
                }
            } else {
                $first = $data[$this->spec[$index]];

                if (count($sku_item) >= count($first)) {
                    foreach ($first as $key => $value) {
                        foreach ($sku_item as $s => $v) {

                            self::$total_item[] = array(
                                'spec_name' => $v['spec_name'] . ',' . $this->spec[$index] . ':' . $value,
                                'spec_key'  => $v['spec_key'] . '_' . $this->spec[$index],
                            );
                        }
                    }
                } else {
                    if ($sku_item) {
                        foreach ($sku_item as $key => $value) {
                            foreach ($first as $fkey => $fvalue) {
                                self::$total_item[] = array(
                                    'spec_name' => $value['spec_name'] . ',' . $this->spec[$index] . ':' . $fvalue,
                                    'spec_key'  => $value['spec_key'] . '_' . $this->spec[$index],
                                );
                            }
                        }
                    }
                }
            }
            if ($index < self::$deep_key) {
                $this->getSkuItem($data, $index + 1, self::$total_item);
            }
        }
        return self::$total_item;

    }

    /**
     * 获取检查商品数据
     * @param bool $isEdit
     * @return mixed
     */
    private function checkGoodsInfo($isEdit = false)
    {

        $bn                             = get_sn(3);
        $data['goods']['name']          = input('post.row.name', '');
        $data['goods']['category_id']  = input('post.row.category_id', '0');
        $data['goods']['goods_type_id'] = input('post.row.goods_type_id', 0);
        $data['goods']['brand_id']      = input('post.row.brand_id', 0);
        $data['goods']['bn']            = input('post.row.bn', $bn);
        if (empty($data['goods']['bn'])) {
            $data['goods']['bn'] = $bn;
        }
        $data['goods']['brief']        = input('post.row.brief', '');
        $data['goods']['intro_content']        = input('post.row.intro_content', '');
        $data['goods']['price']        = input('post.row.price', '');
        $data['goods']['costprice']    = input('post.row.costprice', '');
        $data['goods']['mktprice']     = input('post.row.mktprice', '');
        $data['goods']['weight']       = input('post.row.weight', '');
        $data['goods']['stock']        = input('post.row.stock', '');
        $data['goods']['unit']         = input('post.row.unit', '');
        $data['goods']['market_switch']   = input('post.row.market_switch', '1');
        $data['goods']['top_switch'] = input('post.row.top_switch', '0');

        $data['goods']['image']          = input('post.row.image', '');
        $data['goods']['images']          = input('post.row.images', '');

        $open_spec                     = input('post.open_spec', 0);
        $specdesc                      = input('post.spec/a');
        $new_spec                      = input('post.row.new_spec/a', []);//自定义规格

        //过滤 $specdesc 多规格未选，由于提交会把checkbox未选name也提交
        if($specdesc && count($specdesc) > 1){
            foreach ($specdesc as $k => $v){
                if (empty($v[0])){
                    unset($specdesc[$k]);
                }
            }
        }

        if ($specdesc && $open_spec) {
            if (count($specdesc) == 1) {//优化只一个规格的情况
                $product = input('post.product/a', []);
                foreach ((array)$specdesc as $key => $val) {
                    foreach ($val as $k => $v) {
                        $temp_product_key = $key . ':' . $v;
                        if (!isset($product[$temp_product_key])) {
                            unset($specdesc[$key][$k]);
                        }
                    }
                }
            }
            $data['goods']['spes_desc'] = serialize($specdesc);
            $data['goods']['new_spec']  = serialize($new_spec);
        } else {
            $data['goods']['spes_desc'] = '';
            $data['goods']['new_spec'] = '';
        }

        //商品参数处理
        $params     = [];
        $tempParams = input('post.row.params/a', []);
        if ($tempParams) {
            foreach ($tempParams as $key => $val) {
                if (is_array($val)) {
                    foreach ($val as $vk => $vv) {
                        $params[$key][] = $vk;
                    }
                } else if ($val !== '') {
                    $params[$key] = $val;
                }
            }
            $data['goods']['params'] = serialize($params);
        } else {
            $data['goods']['params'] = '';
        }


        if ($isEdit) {
            $data['goods']['id'] = input('post.goods_id', 0);
            $validate            = new GoodsValidate();
            if (!$validate->scene('edit')->check($data['goods'])) {
                $this->error($validate->getError());
            }
        } else {
            $validate = new GoodsValidate();
            if (!$validate->check($data['goods'])) {
                $this->error($validate->getError());
            }
        }

        return $data;
    }


    /**
     * 获取 商品类型规格 数据
     * 编辑商品是显示
     * @param $type_id
     * @param $goods
     * @return array
     */
    private function getEditSpec($type_id, $goods)
    {
        //判断传递的商品数据 是否是数组 还是对象实例 转数据
        if (!is_array($goods)) $goods = $goods->toArray();

        $result = [
            'status' => false,
            'msg'    => '',
            'data'   => '',
        ];
        if (!$type_id) {
            $this->error('类型不能为空');
        }
        $spes_desc = unserialize($goods['spes_desc']);
        $new_spec  = unserialize($goods['new_spec']);

        $goodsTypeModel = new GoodsType();
        //获取商品类型 绑定的 参数和属性
        $res            = $goodsTypeModel->getTypeValue($type_id);


        /**
         * 修复类型值问题，避免修改规格值，导致无法显示
         */
        $temp_new_spec = unserialize($goods['new_spec']);
        if ($temp_new_spec && is_array($temp_new_spec) && $spes_desc == '') {
            //先重新定义new_spec
            $spec = $res['data']['spec'];
            foreach ((array)$spec as $key => $val) {
                foreach ((array)$temp_new_spec as $tkey => $tval) {
                    $first = array_shift($val['spec']['spec_value']);
                    unset($temp_new_spec[$tkey]);
                    $temp_new_spec[$first['id']] = $tval;
                }
            }
            foreach ($goods['products'] as $key => $val) {
                $pspes_desc = $val['spes_desc'];
                list($spec_name, $spec_value) = explode(':', $pspes_desc);
                foreach ($temp_new_spec as $key => $val) {
                    if ($val[0] == $spec_value) {
                        $spes_desc[$spec_name][$key] = $spec_value;
                    }
                }
            }
            $new_spec = $temp_new_spec;
        }

        $this->assign('goods', $goods);

        $html       = '';
        $customSpec = false;//是否可以使用自定义规格

        if ($res['status'] == true) {
            $this->assign('typeInfo', $res['data']);

            if (!empty($res['data']['spec'])) {
                $spec = [];
                $spec = $this->getSpecData($res['data']['spec'], $spes_desc, $new_spec);

                if (count($spec) <= 2) {//规格超过2种的，不允许自定义
                    $customSpec = true;
                }

                //有规格值调整的时候需要操作一遍下面的逻辑
                if ($spes_desc && $customSpec) {
                    $temp_new_spec = unserialize($goods['new_spec']);
                    $spec          = $res['data']['spec'];
                    foreach ((array)$spec as $key => $val) {
                        $current = $val['spec']['spec_value'];
                        foreach ((array)$temp_new_spec as $tkey => $tval) {
                            //$first = array_shift($val['spec']['spec_value']);
                            $first = current($current);

                            if ($first && $tval) {
                                next($current);
                                unset($temp_new_spec[$tkey]);
                                $temp_new_spec[$first['id']] = $tval;
                            }
                        }

                    }

                    if($temp_new_spec){
                        $temp_spes_desc = [];
                        foreach ($goods['products'] as $key => $pval) {
                            $pspes_desc = $pval['spes_desc'];
                            $pspes_desc = explode(',', $pspes_desc);
                            foreach ($pspes_desc as $pk => $pv) {
                                list($spec_name, $spec_value) = explode(':', $pv);
                                foreach ($temp_new_spec as $key => $val) {
                                    if ($val[0] == $spec_value) {
                                        $temp_spes_desc[$spec_name][$key] = $spec_value;
                                    }
                                }
                            }
                        }
                    }
                    $new_spec  = $temp_new_spec;
                    $spes_desc = $temp_spes_desc;
                    //避免后面修改规格后无法显示，需要再来一遍
                    $spec = $this->getSpecData($spec, $spes_desc, $new_spec);
                }
                $this->assign('spec', $spec);
            }

            $this->assign('customSpec', $customSpec);
            if (empty($res['data']['spec'])) {
                $this->assign('canOpenSpec', 'false');
            } else {
                $this->assign('canOpenSpec', 'true');
            }
            //获取参数信息

            $typeParams           = $res['data']['params'];

            $this->assign('typeParams', $typeParams);
            //解析参数信息
            $params = [];
            if ($goods['params']) {
                $params = unserialize($goods['params']);
            }
            $this->assign('goodsParams', $params);
            $items = [];

            if ($spes_desc) {
                $specValue = [];
                $total     = count($spes_desc);
                foreach ($spes_desc as $key => $val) {
                    $this->spec[] = $key;
                }
                $items = $this->getSkuItem($spes_desc, -1);

                //循环货品
                foreach ($goods['products'] as $product) {
                    foreach ($items as $key => $ispec) {
                        if ($ispec['spec_name'] == $product['spes_desc']) {
                            $items[$key]               = array_merge((array)$ispec, (array)$product);
                            $items[$key]['product_id'] = $product['id'];
                        }
                    }
                }

            } else {
                $this->assign('product', $goods['products'][0]);
            }

            $this->assign('items', $items);

            $this->view->engine->layout(false);

            $html = $this->fetch('editGetSpecHtml');
            $this->view->engine->layout(true);

            $result['status'] = true;
            $result['data']   = $html;
        }
        return $result;
    }

    /**
     * 获取新的spec
     *
     * @param array $data
     * @param array $spes_desc
     * @param array $new_spec
     *
     * @return array
     */
    public function getSpecData($data = [], $spes_desc = [], $new_spec = [])
    {
        $spec = [];
        foreach ((array)$data as $key => $val) {
            $spec[$key]['name']      = $val['spec']['name'];
            $spec[$key]['specValue'] = $val['spec']['spec_value'];
            if ($spes_desc) {
                foreach ((array)$spec[$key]['specValue'] as $vkey => $vval) {
                    $spec[$key]['specValue'][$vkey]['isSelected'] = 'false';
                    if (isset($new_spec[$vval['id']])) {
                        $vval['value']                           = $new_spec[$vval['id']][0];
                        $spec[$key]['specValue'][$vkey]['value'] = $new_spec[$vval['id']][0];
                    }
                    foreach ($spes_desc as $gk => $gv) {
                        foreach ($gv as $v) {
                            if ($v == $vval['value']) {
                                $spec[$key]['specValue'][$vkey]['isSelected'] = 'true';
                            }
                        }
                    }
                }
            }
        }
        return $spec;
    }

    /**
     * 真实删除 （回收站删除）
     */
    public function destroy($ids = "")
    {
        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        if ($ids) {
            $this->model->where($pk, 'in', $ids);
        }
        $count = 0;
        Db::startTrans();
        try {
            $list = $this->model->onlyTrashed()->select();
            foreach ($list as $k => $v) {
                $count += $v->delete(true);
                //删除关联数据 货品
                $v->products()->delete();
            }
            //删除货品数据
            Db::commit();
        } catch (PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        } else {
            $this->error(__('No rows were deleted'));
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }
}
